﻿using System;
using System.Diagnostics;
using System.Reflection;
using System.Text;

namespace RaGE_JD
{
    internal class Utils : Object
    {
        // Gets our version for the title bar...
        internal static string Version
        {
            get
            {
                var asm = Assembly.GetExecutingAssembly();
                var fvi = FileVersionInfo.GetVersionInfo(asm.Location);
                return String.Format("{0}", fvi.FileVersion);
            }
        }

        internal static byte[] GetBytesGBK(string value)
        {
            var enc = Encoding.GetEncoding("GBK");
            var target = new byte[128];
            var source = enc.GetBytes(value);
            Array.Copy(source, target, target.Length > source.Length ? source.Length : target.Length);
            return target;
        }

        // encode string to Base64
        internal string Base64Encode(string data)
        {
            try
            {
                return Convert.ToBase64String(Encoding.UTF8.GetBytes(data));
            }
            catch (Exception e)
            {
                throw new Exception("Error in base64Encode: \n" + e.Message);
            }
        }

        // encode alternate
        internal string Encode64(string str)
        {
            var encbuff = Encoding.UTF8.GetBytes(str);
            return Convert.ToBase64String(encbuff);
        }

        // decode string from Base64
        internal string Base64Decode(string data)
        {
            try
            {
                var encoder = new UTF8Encoding();
                var utf8Decode = encoder.GetDecoder();

                var decodedChar = new char[utf8Decode.GetCharCount(Convert.FromBase64String(data), 0, Convert.FromBase64String(data).Length)];
                utf8Decode.GetChars(Convert.FromBase64String(data), 0, Convert.FromBase64String(data).Length, decodedChar, 0);
                var result = new String(decodedChar);
                return result;
            }
            catch (Exception e)
            {
                throw new Exception("Error in base64Decode: \n" + e.Message);
            }
        }

        // decode alternate
        internal string Decode64(string str)
        {
            var decbuff = Convert.FromBase64String(str);
            return Encoding.UTF8.GetString(decbuff);
        }

        internal static string Decrypt(int key, byte[] text)
        {
            var result = "";

            for (var i = 0; i < text.Length; i += 2)
            {
                var dbyte = BitConverter.GetBytes((short)key);

                // XOR decoding to receive Unicode character code
                dbyte[0] ^= text[i];
                dbyte[1] ^= text[i + 1];
                result += BitConverter.ToChar(dbyte, 0);
            }
            return result.TrimEnd(new[] { '\0' });
        }

        internal static byte[] Encrypt(int key, string text, int length, bool appendZero)
        {
            var result = appendZero ? new byte[length + 2] : new byte[length];

            for (var i = 0; i < result.Length; i += 2)
            {
                var dbyte = BitConverter.GetBytes((short)key);
                result[i] = dbyte[0];
                result[i + 1] = dbyte[1];

                if (i / 2 >= text.Length) continue;

                dbyte = BitConverter.GetBytes(text[i / 2]);
                result[i] ^= dbyte[0];
                result[i + 1] ^= dbyte[1];
            }
            /*
                if(appendZero)
                {
                    dbyte = BitConverter.GetBytes((short)key);
                    result[result.Length-2] = dbyte[0];//^(unsigned char)0;
                    result[result.Length-1] = dbyte[1];//^(unsigned char)0;
                }
            */
            return result;
        }

        internal static string ByteArrayToHexString(byte[] value)
        {
            return BitConverter.ToString(value);
        }

        internal static byte[] HexStringToByteArray(string value)
        {
            // Convert from Hex to byte[]
            var hex = value.Split(new[] { '-' });
            var bytes = new byte[hex.Length];

            for (var i = 0; i < hex.Length; i++)
                bytes[i] = Convert.ToByte(hex[i], 16);

            return bytes;
        }

        internal static string ByteArrayToGBKString(byte[] text)
        {
            var enc = Encoding.GetEncoding("GBK");
            return enc.GetString(text).Split(new[] { '\0' })[0];
        }

        internal static byte[] GBKStringToByteArray(string text, int length)
        {
            var enc = Encoding.GetEncoding("GBK");
            var target = new byte[length];
            var source = enc.GetBytes(text);

            Array.Copy(source, target, target.Length > source.Length ? source.Length : target.Length);

            return target;
        }

        internal static string ByteArrayToUnicodeString(byte[] text)
        {
            var enc = Encoding.GetEncoding("Unicode");
            return enc.GetString(text).Split(new[] { '\0' })[0];
        }

        internal static byte[] UnicodeStringToByteArray(string text, int length)
        {
            var enc = Encoding.GetEncoding("Unicode");
            var target = new byte[length];
            var source = enc.GetBytes(text);

            Array.Copy(source, target, target.Length > source.Length ? source.Length : target.Length);

            return target;
        }
    }
}
